import datetime
import json
import logging
import sys
import hashlib
import cv2
import requests
from PySide2 import QtCore, QtWidgets
from PySide2.QtCore import Qt, QTimer
from PySide2.QtGui import QFont, QImage, QPixmap
from PySide2.QtUiTools import QUiLoader
from PySide2.QtWidgets import QApplication, QMainWindow, QMessageBox, QDialog, QLabel, QLineEdit, QPushButton, \
    QVBoxLayout, QHeaderView, QAbstractItemView, QTableWidgetItem


def hash_password(password):
    salt = "myS@1t"
    # 加盐处理
    salted_password = salt + password
    # 使用SHA-256算法进行哈希
    hashed_password = hashlib.sha256(salted_password.encode()).hexdigest()
    return hashed_password

def scan_camere():
    '''
    扫描摄像头
    @return:摄像头list
    '''
    camera_list = []
    for i in range(10):
        cap = cv2.VideoCapture(i, cv2.CAP_DSHOW)
        if cap.isOpened():
            camera_list.append(i)
            cap.release()

    logging.info("scan_camere")
    logging.info(camera_list)
    return camera_list

def show_msg(title, msg):
    # 创建一个警告对话框，并显示它
    msg_box = QMessageBox()
    msg_box.setIcon(QMessageBox.NoIcon)
    msg_box.setText(msg)
    msg_box.setWindowTitle(title)
    msg_box.setStandardButtons(QMessageBox.Ok)
    msg_box.setDefaultButton(QMessageBox.Ok)

    msg_box.exec_()

def log_init():
    """
        初始化日志
        @return:
        """
    logging.basicConfig(
        # filename= str(datetime.date.today()) + '.log',
        level=logging.DEBUG,
        format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')

    logging.info("START")
class LoginDialog(QDialog):
    server_url = 'http://127.0.0.1:5000'
    headers = {'Content-Type': 'application/json'}
    def __init__(self):
        super().__init__()
        # 取消上下文帮助按钮
        self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint)
        self.user_name = ''
        self.setWindowTitle("登录")
        self.resize(300, 150)
        self.welcome = QLabel("欢迎使用，请登录")
        font = QFont()
        font.setPointSize(20)  # 设置字体大小为20
        self.welcome.setFont(font)  # 将字体应用到QLabel控件中
        self.welcome.setAlignment(Qt.AlignCenter)
        self.username_label = QLabel("用户名")
        self.password_label = QLabel("密码")
        self.username_edit = QLineEdit()
        self.password_edit = QLineEdit()

        self.password_edit.setEchoMode(QLineEdit.Password)
        self.login_button = QPushButton("登录")
        self.register_button = QPushButton("注册")
        self.login_button.setStyleSheet("height: 80px;")
        self.register_button.setStyleSheet("height: 40px;")

        layout = QVBoxLayout()
        layout.addWidget(self.welcome)
        layout.addWidget(self.username_label)
        layout.addWidget(self.username_edit)
        layout.addWidget(self.password_label)
        layout.addWidget(self.password_edit)
        layout.addWidget(self.login_button)
        layout.addWidget(self.register_button)
        self.setLayout(layout)
        self.login_button.clicked.connect(self.login)
        self.register_button.clicked.connect(self.register)

    def userName(self):
        return self.user_name
    def login(self):
        username = self.username_edit.text()
        password = self.password_edit.text()
        password = hash_password(password)
        self.password_edit.setText("")

        data = {
            'username': username,
            'password': password,
        }
        url = self.server_url + '/login'
        try:
            response = requests.post(url, headers=self.headers, data=json.dumps(data))
            response_json = response.json()

        except requests.exceptions.ConnectionError:
            show_msg("提示", "连接服务器失败！请检查网络或者配置！")
            return
        if response.ok:
            if response_json['message'] == 'Logged in successfully':
                self.user_name = username
                self.accept()
                return
        show_msg("提示", response_json['message'])



    def register(self):
        register_dialog = QDialog()
        register_dialog.setWindowTitle("注册")
        register_dialog.resize(300, 150)
        welcome = QLabel("注册引导")
        font = QFont()
        font.setPointSize(20)  # 设置字体大小为20
        welcome.setFont(font)  # 将字体应用到QLabel控件中
        username_label = QLabel("用户名")
        password_label = QLabel("密码")
        username_edit = QLineEdit()
        password_edit = QLineEdit()
        password_edit.setEchoMode(QLineEdit.Password)
        ok_button = QPushButton("确定")
        cancel_button = QPushButton("取消")
        ok_button.setStyleSheet("height: 80px;")
        cancel_button.setStyleSheet("height: 40px;")
        register_layout = QVBoxLayout()
        register_layout.addWidget(welcome)
        register_layout.addWidget(username_label)
        register_layout.addWidget(username_edit)
        register_layout.addWidget(password_label)
        register_layout.addWidget(password_edit)
        register_layout.addWidget(ok_button)
        register_layout.addWidget(cancel_button)
        register_dialog.setLayout(register_layout)

        def register_dialog_accepted():
            username = username_edit.text()
            password = password_edit.text()
            password = hash_password(password)
            password_edit.setText("")
            self.password_edit.setText("")


            data = {
                'username': username,
                'password': password,
                # 'email': 'example_email@example.com'
            }
            url = self.server_url + '/register'

            try:
                response = requests.post(url, headers=self.headers, data=json.dumps(data))
                response_json = response.json()
            except requests.exceptions.ConnectionError:
                show_msg("提示", "连接服务器失败！请检查网络或者配置！")
                return

            show_msg("提示", response_json['message'])






        ok_button.clicked.connect(register_dialog.accept)
        cancel_button.clicked.connect(register_dialog.reject)
        register_dialog.accepted.connect(register_dialog_accepted)

        register_dialog.exec_()


class MainWindow():
    def __init__(self,username):
        self.timer_camera = QTimer()
        self.ui = QUiLoader().load('./main.ui')
        self.ui.setWindowTitle("主窗口")
        self.username = username
        self.ui.welcome_label.setText(f"你好，{self.username}")
        self.ui.open_cam_btn.clicked.connect(self.open_camera)
        self.ui.close_cam_btn.clicked.connect(self.close_cam)

        self.ui.record.resizeColumnsToContents() # 根据内容调整列宽
        # self.ui.record.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)  # 自适应

        self.ui.record.setColumnWidth(0, 300)


        self.addRecord(200, 182)
        self.addRecord(100, 2)
        self.addRecord(100, 2)
        self.addRecord(100, 2)
        self.addRecord(100, 2)
        self.addRecord(100, 2)
        self.addRecord(100, 2)








    def update_camera1_frame(self):
        try:
            ret, frame = self.cap.read()
            if ret:
                try:
                    # 将OpenCV视频帧转换为PySide2图像
                    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                    frame = cv2.resize(frame, None, fx=0.8, fy=0.8)
                    image = QImage(frame, frame.shape[1], frame.shape[0], QImage.Format_RGB888)
                    pixmap = QPixmap.fromImage(image)
                    self.ui.camera_view.setPixmap(pixmap)
                except Exception as e:
                    self.close_cam()
                    logging.error(str(e))
        except Exception as e:
            self.timer_camera.stop()
            logging.error(str(e))

    def addRecord(self, count,qualified):
        current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        row = self.ui.record.rowCount()
        self.ui.record.insertRow(row)
        self.ui.record.setEditTriggers(QAbstractItemView.NoEditTriggers)  # 不可编辑
        # self.ui.tableWidget.setTextAlignment(Qt.AlignHCenter )  # 居中显示
        row_now = row + 1
        logging.debug(f"{row_now},{current_time},{count},{qualified},{qualified/count}")
        self.ui.record.scrollToBottom()
        item1 = QTableWidgetItem(current_time)
        item2 = QTableWidgetItem(str(count))
        item3 = QTableWidgetItem(str(qualified))
        item4 = QTableWidgetItem(str(qualified/count * 100) + '%')

        item1.setTextAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter)
        item2.setTextAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter)
        item3.setTextAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter)
        item4.setTextAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter)


        self.ui.record.setItem(row, 0, item1)
        self.ui.record.setItem(row, 1, item2)
        self.ui.record.setItem(row, 2, item3)
        self.ui.record.setItem(row, 3, item4)
    def close_cam(self):
        self.ui.camera_view.setText("图像")
        try:
            self.timer_camera.stop()
            self.cap.release()
        except AttributeError:
            pass
    def open_camera(self):
        # 创建一个定时器，用于定时更新视频流
        self.camera_list = scan_camere()
        self.timer_camera.timeout.connect(self.update_camera1_frame)
        if len(self.camera_list) != 0:
            # 打开摄像头
            self.cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
            self.cap.set(3, 1280)
            self.cap.set(4, 720)
            if not self.cap.isOpened():
                self.show_msg("错误", "无法打开摄像头")
                logging.error('无法打开摄像头')
            else:
                # 启动定时器
                logging.info('成功打开摄像头')
                self.timer_camera.start(30)
        else:
            self.show_msg("错误", "未发现摄像头")
            logging.error('未发现摄像头')

    def show_msg(self, title, msg):
        # 创建一个警告对话框，并显示它
        msg_box = QMessageBox()
        msg_box.setIcon(QMessageBox.NoIcon)
        msg_box.setText(msg)
        msg_box.setWindowTitle(title)
        msg_box.setStandardButtons(QMessageBox.Ok)
        msg_box.setDefaultButton(QMessageBox.Ok)

        msg_box.exec_()


if __name__ == "__main__":
    log_init()
    debug = 1
    app = QApplication(sys.argv)
    font = QFont()
    font.setPointSize(14)  # 设置字体大小
    app.setFont(font)
    if not debug:
        login_dialog = LoginDialog()
        if login_dialog.exec_() == QDialog.Accepted:
            main = MainWindow(login_dialog.userName())
            main.ui.show()
            app.exec_()
    else:
        main = MainWindow("developer")
        main.ui.show()
        app.exec_()
